package com.example.WebSocket;

import com.example.utils.JsonUtils;
import com.fasterxml.jackson.databind.JsonNode;
import jakarta.websocket.*; // 替换 javax.websocket 为 jakarta.websocket
import org.glassfish.tyrus.client.ClientManager;
import org.springframework.http.HttpHeaders;
import org.json.JSONObject;

import java.io.IOException;
import java.net.URI;
import java.nio.ByteBuffer;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;

/**
 * 连接实时短语音识别的websocket的连接
 */
@ClientEndpoint
public class AsrWebSocketClient {
    private Session session;
    private StringBuilder result = new StringBuilder();
    private String fanhui; // 新增回调接口
    private boolean isFirstResult = true; // 标记是否是第一次收到结果
    private StringBuilder resultBuilder;

    public String getFanhui(){
        return fanhui;
    }
    public void setFanhui(){
        this.fanhui = null;
        this.result = new StringBuilder();
        this.isFirstResult = true;
    }

    public void connect(String url, HttpHeaders headers) throws Exception {
        ClientManager client = ClientManager.createClient();
        final Map<String, List<String>> finalHeaders = new HashMap<>();
        headers.forEach((k, v) -> finalHeaders.put(k, v));

        // 打印连接参数信息
        System.out.println("WebSocket 连接 URL: " + url);
        System.out.println("请求头信息:");
        headers.forEach((k, v) -> System.out.println(k + ": " + v));

        ClientEndpointConfig config = ClientEndpointConfig.Builder.create()
                .configurator(new ClientEndpointConfig.Configurator() {
                    @Override
                    public void beforeRequest(Map<String, List<String>> requestHeaders) {
                        requestHeaders.putAll(finalHeaders); // 添加自定义请求头
                    }
                })
                .build();

        // 设置 WebSocket 协议版本
        client.getProperties().put("org.glassfish.tyrus.client.websocket.version", "13");

        Endpoint endpoint = new Endpoint() {
            @Override
            public void onOpen(Session session, EndpointConfig config) {
                AsrWebSocketClient.this.onOpen(session); // 调用 onOpen 方法
                // 注册消息处理器
                session.addMessageHandler(new MessageHandler.Whole<String>() {
                    @Override
                    public void onMessage(String message) {
                        AsrWebSocketClient.this.onMessage(message);
                    }
                });
            }

            @Override
            public void onClose(Session session, CloseReason closeReason) {
                System.out.println("WebSocket 连接关闭: " + closeReason);
            }

            @Override
            public void onError(Session session, Throwable thr) {
                System.err.println("WebSocket 连接错误: " + thr.getMessage());
                thr.printStackTrace(); // 打印堆栈跟踪
            }
        };
        client.connectToServer(endpoint, config, new URI(url)); // 连接到 WebSocket 服务器
    }

    @OnOpen
    public void onOpen(Session session) {
        this.session = session;
        // 发送启动消息
        sendStartMessage();
    }

    private void sendStartMessage() {
        Map<String, Object> startMsg = new HashMap<>();
        startMsg.put("type", "started");
        startMsg.put("request_id", UUID.randomUUID().toString());
        startMsg.put("asr_info", Map.of(
                "front_vad_time", 6000,
                "end_vad_time", 2000,
                "audio_type", "pcm",
                "chinese2digital", 1,
                "punctuation", 2
        ));
        startMsg.put("business_info", "{\"scenes_pkg\":\"com.tencent.qqlive\", \"editor_type\":\"3\", \"pro_id\":\"2addc42b7ae689dfdf1c63e220df52a2-2020\"}");
        session.getAsyncRemote().sendText(JsonUtils.toJson(startMsg));
    }

    public void sendAudio(byte[] audioData) {
        session.getAsyncRemote().sendBinary(ByteBuffer.wrap(audioData));
    }

    private void onMessage(String message) {
        try {
            JSONObject json = new JSONObject(message);
            String action = json.getString("action");
            int code = json.getInt("code");
            
            if ("error".equals(action)) {
                System.out.println("收到错误消息: " + message);
                return;
            }
            
            if ("started".equals(action)) {
                System.out.println("连接成功: " + message);
                return;
            }
            
            if ("result".equals(action) && code == 0) {
                JSONObject data = json.getJSONObject("data");
                String text = data.getString("text");
                int reformation = data.getInt("reformation");
                boolean isLast = data.getBoolean("is_last");
                
                System.out.println("收到识别结果: " + text + ", reformation=" + reformation + ", isLast=" + isLast);
                
                // 忽略空文本
                if (text == null || text.trim().isEmpty()) {
                    return;
                }
                
                if (isFirstResult) {
                    // 第一次收到结果，直接设置
                    resultBuilder = new StringBuilder(text);
                    isFirstResult = false;
                } else {
                    // 后续结果，根据reformation处理
                    if (reformation == 1) {
                        // 修正模式，替换整个结果
                        resultBuilder = new StringBuilder(text);
                    } else {
                        // 追加模式，检查重叠
                        int overlap = findOverlap(resultBuilder.toString(), text);
                        if (overlap < text.length()) {
                            resultBuilder.append(text.substring(overlap));
                        }
                    }
                }
                
                if (isLast) {
                    String finalResult = resultBuilder.toString();
                    // 检查结果是否合理
                    if (finalResult.length() > 1) { // 至少要有两个字符
                        setFanhui(finalResult);
                    } else {
                        System.out.println("忽略过短的识别结果: " + finalResult);
                    }
                }
            }
        } catch (Exception e) {
            System.out.println("处理消息异常: " + e.getMessage());
            e.printStackTrace();
        }
    }

    private int findOverlap(String existing, String newText) {
        // 从后向前查找重叠部分
        int minLength = Math.min(existing.length(), newText.length());
        for (int i = minLength; i > 0; i--) {
            if (existing.endsWith(newText.substring(0, i))) {
                return i;
            }
        }
        return 0;
    }

    public void setFanhui(String fanhui) {
        this.fanhui = fanhui;
        this.isFirstResult = true; // 重置状态
        this.resultBuilder = null;
    }

    public void closeConnection() throws IOException {
        try {
            if (session != null && session.isOpen()) {
                session.getAsyncRemote().sendBinary(ByteBuffer.wrap("--close--".getBytes()));
                session.close();
            }
        } catch (Exception e) {
            System.out.println("关闭连接时出错: " + e.getMessage());
        }
    }
}
